package vip.xiaonuo.biz.modular.nccAi.util;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import nccloud.open.api.auto.token.cur.utils.APICurUtils;
import nccloud.open.api.auto.token.cur.utils.Encryption;
import nccloud.open.api.auto.token.cur.utils.SHA256Util;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import vip.xiaonuo.biz.modular.nccAi.util.nccReq.*;
import vip.xiaonuo.biz.modular.nccAi.util.nccRes.NccCommRes;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.dev.api.DevConfigApi;

import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * ClassName:Ncc接口
 * Description:
 *
 * @Author:薛守立
 * @CreateTime:2025/4/16 15:52
 */
public class NccClient {

    private static String accessToken = "";

    private static String tokenJson = "";

    public static APICurUtils nccSDK = null;
    /** accessToken的过期时间 */
    private static long EXPIRES_TIME = 990 ;

    private static final String NCC_API_URL = "NCC_API_URL";

    private static final String NCC_BIZ_CENTER = "NCC_BIZ_CENTER";

    private static final String NCC_CLIENT_ID = "NCC_CLIENT_ID";

    private static final String NCC_CLIENT_SECRET = "NCC_CLIENT_SECRET";

    private static final String NCC_PUB_KEY="NCC_PUB_KEY";

    private static final String NCC_FILE_UPLOAD_URL="NCC_FILE_UPLOAD_URL";

    private static final String NCC_IMAGE_UPLOAD_URL="NCC_IMAGE_UPLOAD_URL";

    private static final String NCC_CON_CREATE="NCC_CON_CREATE";

    private static final String NCC_PAYMENT="NCC_PAYMENT";

    public static String conUrl="";

    public static String payUrl="";

    private static Logger logger = LoggerFactory.getLogger(CozeClient.class);

    public NccClient(String userCode) {
        try {
            this.accessToken = initClient(userCode);
        } catch (Exception e) {
            throw new RuntimeException("ncc客户端初始化错误，请检查");
        }

    }

    public NccClient() {
    }

    public static String initClient(String userCode) throws Exception {
        String baseUrl = "http://117.157.233.238:9080/";
        // ncc IP地址
        String ip = "117.157.233.238";
        // ncc 端口
        String port = "9080";
        ObjectMapper mapper = new ObjectMapper();
        // 配置ncc的SDK
        nccSDK = new APICurUtils();
        // 文件配置相关属性
        DevConfigApi devConfigApi = SpringUtil.getBean(DevConfigApi.class);
        String bizCenter = devConfigApi.getValueByKey(NCC_BIZ_CENTER);
        if(ObjectUtil.isEmpty(bizCenter)) {
            throw new CommonException("ncc客户端未正确配置：bizCenter为空");
        }
        String clientId = devConfigApi.getValueByKey(NCC_CLIENT_ID);
        if(ObjectUtil.isEmpty(clientId)) {
            throw new CommonException("ncc客户端未正确配置：clientId为空");
        }
        String publicKey = devConfigApi.getValueByKey(NCC_PUB_KEY);
        if(ObjectUtil.isEmpty(publicKey)) {
            throw new CommonException("ncc客户端未正确配置：公钥为空");
        }
        String clientSecret = devConfigApi.getValueByKey(NCC_CLIENT_SECRET);
        if(ObjectUtil.isEmpty(clientSecret)) {
            throw new CommonException("ncc客户端未正确配置：clientSecret为空");
        }
        if(ObjectUtil.isEmpty(userCode)) {
            throw new CommonException("ncc客户端未正确配置：userCode为空");
        }
        conUrl = devConfigApi.getValueByKey(NCC_CON_CREATE);

        if(ObjectUtil.isEmpty(conUrl)) {
            throw new CommonException("ncc客户端未正确配置：NCC_CON_CREATE为空");
        }

        payUrl = devConfigApi.getValueByKey(NCC_PAYMENT);
        if(ObjectUtil.isEmpty(payUrl)) {
            throw new CommonException("ncc客户端未正确配置：NCC_PAYMENT为空");
        }
        String nccAccessToken = devConfigApi.getToken("NCC_ACCESS_TOKEN");
        logger.info("nccAccessToken 为：{}", nccAccessToken);
        if(nccAccessToken.isEmpty()){
            // 参数组织
            Map<String, String> paramMap = new HashMap();
            paramMap.put("grant_type", "client_credentials");
            paramMap.put("client_id", clientId);
            paramMap.put("client_secret", URLEncoder.encode(Encryption.pubEncrypt(publicKey, clientSecret), "UTF-8"));
            paramMap.put("biz_center", bizCenter);
            paramMap.put("usercode", userCode);
            String sign = SHA256Util.getSHA256(clientId + clientSecret + publicKey, publicKey);
            paramMap.put("signature", sign);
            String url = baseUrl + "nccloud/opm/accesstoken";
            String mediaType = "application/x-www-form-urlencoded";
            String res = NccRequest.doPost(url, paramMap, mediaType, (Map)null, "");
            JSONObject jsonObject = JSONUtil.parseObj(res);
            if (jsonObject.getBool("success")) {
                JSONObject data = jsonObject.getJSONObject("data");
                tokenJson = res;
                accessToken = data.getStr("access_token");
                System.out.println("NCC解析json获取token成功：{}" + accessToken);
                // 保存ncc相关token
                devConfigApi.saveToken(tokenJson, EXPIRES_TIME, "NCC_ACCESS_TOKEN");
            } else {
                String message = jsonObject.getStr("message");
                System.out.println("获取token错误：{}" + message);
            }
        }
        nccSDK.init(ip, port, bizCenter, clientId, clientSecret, publicKey, userCode, null);
        return nccAccessToken;
    }

    /**
     * 创建付款合同
     *
     * @param conExpenseParam
     * @return
     */
    public JSONObject createConExpense(ConExpenseParam conExpenseParam, String userCode) throws Exception {
        String token = initClient(userCode);
        nccSDK.setApiUrl(conUrl);
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, ConExpenseParam> param = new HashMap<>();
        param.put("fct_ap", conExpenseParam);
        String jsonString = objectMapper.writeValueAsString(param);
        String resultJson = nccSDK.getAPIRetrun(token, jsonString);
        return new JSONObject(resultJson);

    }

    /**
     * 创建付款单
     *
     * @param paymentBillParam
     * @return
     */
    public JSONObject createPaymentBill(PaymentBillParam paymentBillParam, String userCode) throws Exception {
        String token = initClient(userCode);
        nccSDK.setApiUrl(payUrl);
        // 格式化成json字符串
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonString = objectMapper.writeValueAsString(paymentBillParam);
        String resultJson = nccSDK.getAPIRetrun(token, jsonString);
        JSONObject obj = JSONUtil.parseObj(resultJson);
        return obj.getJSONObject("data");
    }

    /**
     * 查询付款单据
     *
     * @param searchParam
     * @return
     */
    public JSONObject searchPaymentBill(PaymentBillSearchParam searchParam, String userCode) throws Exception {
        String token = initClient(userCode);
        String searchUrl = "nccloud/api/arap/paybill/query";
        nccSDK.setApiUrl(searchUrl);
        // 格式化成json字符串
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonString = objectMapper.writeValueAsString(searchParam);
        String resultJson = nccSDK.getAPIRetrun(token, jsonString);
        return new JSONObject(resultJson);
    }


    /**
     * 创建收款单
     * @param gatherBillAddParam
     * @return
     */
    public JSONObject createGatherBill(GatherBillAddParam gatherBillAddParam, String userCode) throws Exception {
        String token = initClient(userCode);
        String url = "nccloud/api/arap/gatheringbill/insert";
        nccSDK.setApiUrl(url);
        // 格式化成json字符串
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonString = objectMapper.writeValueAsString(gatherBillAddParam);
        String resultJson = nccSDK.getAPIRetrun(token, jsonString);
        return new JSONObject(resultJson);
    }

    /**
     * 查询收款合同
     * @param searchParam
     * @param userCode
     * @return
     * @throws Exception
     */
    public JSONObject searchIncomeContract(IncomeContractSearchParam searchParam, String userCode) throws Exception {
        String token = initClient(userCode);
        nccSDK.setApiUrl("nccloud/api/fct/ar/query");
        // 格式化成json字符串
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonString = objectMapper.writeValueAsString(searchParam);
        String resultJson = nccSDK.getAPIRetrun(token, jsonString);
        return new JSONObject(resultJson);
    }

    /**
     * 查询收款单
     * @return
     * @throws Exception
     */
    public JSONObject searchGatherBill() throws Exception {
        GatherBillSearchParam searchParam = new GatherBillSearchParam();
        String token = initClient("004374");
        nccSDK.setApiUrl("nccloud/api/arap/gatheringbill/query");
        // 格式化成json字符串
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonString = objectMapper.writeValueAsString(searchParam);
        String resultJson = nccSDK.getAPIRetrun(token, jsonString);
        return new JSONObject(resultJson);
    }

    /**
     * ncc 推送影像
     * @param filePath
     * @param businessSerialNo ncc接口返回单据的PK主键
     * @return
     */
    public Integer sendDocFile(String filePath, String businessSerialNo){
        File file = new File(filePath);
        String fileName = file.getName();
        String uploadUrl= "http://117.157.233.239:8077/imageUploadServices/uploadDocument";
        String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
        if (StringUtils.isNotBlank(fileName) && StringUtils.isNotBlank(businessSerialNo)) {
            switch (fileType) {
                case "png":
                case "jpg":
                    uploadUrl = "http://117.157.233.239:8077/imageUploadServices/images";
                    break;
                default:
                    uploadUrl = "http://117.157.233.239:8077/imageUploadServices/uploadDocument";
                    break;
            }
        }
        return uploadNccFile(filePath, fileName, businessSerialNo, uploadUrl);
    }

    public Integer uploadNccFile(String filePath, String fileName, String businessSerialNo, String url) {
        Integer state = 2;
        String result = "";
        try {
            HashMap<String, Object> paramMap = new HashMap<>();
            // 文件上传只需将参数中的键指定（默认file），值设为文件对象即可，对于使用者来说，文件上传与普通表单提交并无区别
            File file = new File(filePath);
            paramMap.put("fileByte", file);
            paramMap.put("fileParamName", fileName);
            paramMap.put("businessSerialNo", businessSerialNo);
            // 用友给的工具类Demo中图片类型文件包括fileName参数
            paramMap.put("fileName", fileName);
            // API文档中包含docName参数
            paramMap.put("docName", fileName);
            String res= HttpUtil.post(url, paramMap);
            JSONObject jsonObject = JSONUtil.parseObj(res);
            Integer status = jsonObject.getInt("status");
            String msg = "";
            if (null!=jsonObject.getStr("msg")) {
                msg = jsonObject.getStr("msg");
            } else if(null !=jsonObject.getStr("message")) {
                msg = jsonObject.getStr("message");
            }
            if (null != status && (status == 14 || status == 16 || status == 200)){
                state = 1;
                result = msg;
                logger.info("影像上传成功: " + result);
            } else {
                state = 2;
                result = "影像上传失败: " + msg;
                logger.info("影像上传失败: " + result);
            }
        } catch (Exception e) {
            state = 2;
            result = "影像上传失败: e" + e.toString();
            logger.info("影像上传失败: " + result);
        }
        return state;
    }
}
